package com.colabo.j2ee.web.oaf.security.impl;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.colabo.j2ee.web.core.common.CommonConstants;
import com.colabo.j2ee.web.core.context.CoreInitInfo;
import com.colabo.j2ee.web.core.exception.ServiceException;
import com.colabo.j2ee.web.oaf.security.BadCaptchaException;
import com.colabo.j2ee.web.oaf.security.CaptchaNotFoundException;
import com.colabo.j2ee.web.oaf.security.IUserDetailsService;

/**
 * 扩展认证过滤器，增加验证前逻辑操作方法，和验证后逻辑操作方法
 * 验证前增加preAuthentication方法
 * 验证后重载successfulAuthentication方法和unsuccessfulauthentication方法
 * @author Anthony
 *
 */
public class UsernamePasswordAuthenticationFilterExt extends UsernamePasswordAuthenticationFilter {
	// Instance Fields ======================================
	
	private IUserDetailsService userDetailsService = null;
	private Log logger = LogFactory.getLog(UsernamePasswordAuthenticationFilterExt.class);
	
	// Methods ===============================================
	
	public IUserDetailsService getUserDetailsService() {
		return userDetailsService;
	}

	public void setUserDetailsService(IUserDetailsService userDetailsService) {
		this.userDetailsService = userDetailsService;
	}

	/**
	 * 验证成功后，进行业务操作
	 */
	@Override
	protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
			Authentication authResult) throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("****认证成功，进入认证成功后业务处理****");
		}
		try {
			if (userDetailsService != null) {
				userDetailsService.onSuccessfulAuthentication(request, response, obtainUsername(request));
			}
		} catch (ServiceException e) {
			logger.error("验证成功后，记录登陆信息异常", e);
		} 
		
		try {
			super.successfulAuthentication(request, response, authResult);
		} catch (ServletException e) {
			logger.error("验证成功后，执行success handler失败", e);
		}
	}

	/**
	 * 验证前动作
	 * 此处执行进入验证前的一些业务逻辑，如：验证码验证，转换验证字段等。
	 * 发生异常，抛出AuthenticationException的子类，中断验证步骤。
	 * @param request
	 * @param response
	 */
	protected void preAuthentication(HttpServletRequest request, HttpServletResponse response) {
		//系统配置里的“是否启用验证码”配置项，如果没有配置，则默认不启用
		Boolean isCaptchaCheckEnabled  = CoreInitInfo.getInstance().getBooleanProp("captcha.enabled");
		if (!isCaptchaCheckEnabled) {
			if (logger.isDebugEnabled()) {
				logger.debug("****验证码未启用****");
			}
			return;
		}
		
		if (logger.isDebugEnabled()) {
			logger.debug("****验证码启用****");
		}
		
		//request中获取captcha输入值，未获取到则抛出异常
		String captchaValue = request.getParameter("j_captcha_response");
		if (null == captchaValue || "".equals(captchaValue.trim())) {
			throw new CaptchaNotFoundException("未接收到验证码值");
		}
		
		//如果session中的验证码为空，或者验证码与输入的验证码不一致，则抛出异常
		String rand = (String) request.getSession().getAttribute("Rand");
		if (rand == null || !rand.equals(captchaValue)) {
			throw new BadCaptchaException("验证码验证不符");
		}

	}

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request,
			HttpServletResponse response) throws AuthenticationException {
		this.preAuthentication(request, response);
		return super.attemptAuthentication(request, response);
	}

}
